package com.tmall.testgen.common.util;


import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Comparator {
	
	
	public   boolean compare(Object obj1,Object obj2){
		if(obj1==null&&obj2==null)
			return true;
		
		if(obj1==null||obj2==null)
			return false;
		
//		if(obj1.getClass()!=obj2.getClass())
//			return false;
		try{
    		
    		if(obj1 instanceof Collection){
    			return compareCollection((Collection)obj1,(Collection)obj2);
    		}else if(obj1 instanceof Map){
    			return compareMap((Map)obj1,(Map)obj2);
    		}else{
    			return compareObject(obj1,obj2);
    		}
		}catch(Exception e){
		    return false;
		}
	}
	
	
	private  boolean compareBasicType(Object obj1,Object obj2){
		if((obj1 instanceof Date)&&(obj2 instanceof Date)){
			Date d1=(Date) obj1;
			Date d2=(Date) obj2;
			return d1.getTime()==d2.getTime();
		}
		
		return obj1.equals(obj2);
	}
	
	private  boolean compareCollection(Collection c1,Collection c2){
		if(c1.size()!=c2.size())
			return false;
		
		Iterator c1Iterator=c1.iterator();
		Iterator c2Iterator=c2.iterator();
		
		while(c1Iterator.hasNext()){
			Object o1=c1Iterator.next();
			Object o2=c2Iterator.next();
			
			if(!compare(o1,o2))
				return false;
		}
		
		return true;
	}
	
	private  boolean compareObject(Object obj1,Object obj2){
		
		if(isBasicType(obj1))
			return compareBasicType(obj1,obj2);
		
		Map<String,Object>   obj1FiledValueMap=getFieldMap(obj1);
		Map<String,Object>   obj2FiledValueMap=getFieldMap(obj2);
		if(obj1FiledValueMap.size()==0&&obj2FiledValueMap.size()==0)
			return true;
		if(obj1FiledValueMap.size()==0||obj2FiledValueMap.size()==0){
			return false;
		}
		
		for(String fieldName:obj1FiledValueMap.keySet()){
			if(!compare(obj1FiledValueMap.get(fieldName),obj2FiledValueMap.get(fieldName)))
				return false;
		}
		return true;
	}
	
	private  boolean compareMap(Map m1,Map m2){
		if(m1.size()!=m2.size())
			return false;
		
		for(Object key:m1.keySet()){
			if(!compare(m1.get(key),m2.get(key)))
				return false;
			
		}
		
		return true;
	}
	
	private   Map<String,Object>  getFieldMap(Object obj){
		
		Class objClass=obj.getClass();
        Map<String,Object>fildValueMap=new HashMap<String,Object>();
        
    	Field[] fields=objClass.getDeclaredFields();
    	for(Field field:fields){
    		
    		try{
        		PropertyDescriptor pd = new PropertyDescriptor(field.getName(),objClass);
        	    Method getMethod = pd.getReadMethod();//获得get方法
        	    Object o = getMethod.invoke(obj);//执行get方法返回一个Object
        	    fildValueMap.put(field.getName(), o);
    		}catch(Exception e){
    			
    		}
    	
		}
        
        return fildValueMap;
	}
	private static boolean isBasicType(Object o){
		if(o instanceof String )
			return true;
		
		if(o instanceof Boolean )
			return true;
		if(o instanceof Byte )
			return true;
		if(o instanceof Short )
			return true;
		if(o instanceof Integer )
			return true;
		if(o instanceof Long )
			return true;
		if(o instanceof Float )
			return true;
		if(o instanceof Double )
			return true;
		if(o instanceof Date)
			return true;
		if(o instanceof BigDecimal){
		    return true;
		}
		
		return false;
		
	}

}
